#pragma once

#include "RBTree.hpp"
#include <iostream>

namespace simulation {

	template<class K, class V>
	class map {
	private:
		struct MapKeyOfData {
			const K& operator() (const std::pair<K, V>& kv) const
			{
				return kv.first;
			}
		};

		RBTree<K, std::pair<const K, V>, MapKeyOfData> _RBTree;

	public:
		typedef typename RBTree<K, std::pair<const K, V>, MapKeyOfData>::iterator iterator;
		typedef typename RBTree<K, std::pair<const K, V>, MapKeyOfData>::const_iterator const_iterator;

		std::pair<iterator, bool> insert(const std::pair<K, V>& kv)
		{
			return _RBTree.insert(kv);
		}

		iterator begin()
		{
			return _RBTree.begin();
		}

		const_iterator begin() const
		{
			return _RBTree.begin();
		}

		iterator end()
		{
			return _RBTree.end();
		}

		const_iterator end() const
		{
			return _RBTree.end();
		}

		void inOrder()
		{
			for (const auto& pr : _RBTree)
			{
				std::cout << pr.first << ":" << pr.second << std::endl;
			}
		}

		V& operator[] (const K& key)
		{
			return (*((this->insert(std::make_pair(key, V()))).first)).second;
		}
	};
}